﻿using FlyIL.Misc;
using FlyIL.Trace;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;

namespace FlyIL.Optimizer;



internal class SimplfyRoot
{
    protected List<SimplfyRoot> alist;


    protected ExpByTrace _exp;

    [DebuggerNonUserCode()]
    bool _(Type type)
    {
        return type.BaseType == (this.GetType());
    }


    /// <summary>
    /// 查找分支处理 
    /// </summary>
    [DebuggerNonUserCode()]
    public SimplfyRoot GetSubMatch(Context con, Inst node)
    {

        lock (this)
        {
            if (alist == null)
            {

                alist = new List<SimplfyRoot>();

                var types = Assembly.GetCallingAssembly().GetTypes().Where(_).ToList();


                foreach (var t in types)
                {
                    if (!t.IsAbstract)
                    {
                        object obj = Activator.CreateInstance(t);
                        alist.Add(obj as SimplfyRoot);
                    }
                }

            }
        }

        /// IsMatch 有可能被 覆盖 添加了自身的逻辑， 则需要调用一下
        if (this.IsMatch(con, node, _exp))
            foreach (var u in alist)
            {
                if (u.IsMatch(con, node, _exp))
                    return u;
            }

        return null;

    }


    /// <summary>
    /// 覆盖时，不需要再调用 基类方法  
    /// </summary>
    [DebuggerNonUserCode()]
    public virtual bool IsMatch(Context con, Inst node, ExpByTrace exp = null)
    {
        /// 如果是条件跳转 或者条件计算， 暂不处理 
        if (node.Opt == Opt.nop || node.ExpCon != null)
            return false;

        return true;
    }


    // 默认是交给 子类处理 , 具体节点 覆盖此逻辑即可 
    // ftp://note 交由子节的表达式，是自身维护的 表达式， 而不是由上层传过来的 

    public virtual void Do(Context con, Inst node, ExpByTrace expression = null)
    {
        var simp = GetSubMatch(con, node);
        simp?.Do(con, node, _exp);
    }

}

/********************
 * 
 * 如果是具体逻辑 ， 需要 覆盖 IsMatch Do 两个方法 
 * 
 * 如果是逻辑的中的虚拟节点 ， 只需要 覆盖 IsMatch, 并在其中维护 exp 即可 
 * 
 * 
 * *************************/







